package org.news.web.controller.app;

import cn.dev33.satoken.annotation.SaIgnore;
import com.aliyuncs.exceptions.ClientException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.dromara.common.core.domain.R;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.system.domain.SysOss;
import org.dromara.system.mapper.SysOssMapper;
import org.news.web.constant.CategoriesConstant;
import org.news.web.constant.NewsConstant;
import org.news.web.domain.Creators;
import org.news.web.domain.News;
import org.news.web.domain.Subscriptions;
import org.news.web.domain.bo.*;
import org.news.web.domain.vo.*;
import org.news.web.mapper.CreatorsMapper;
import org.news.web.mapper.NewsMapper;
import org.news.web.mapper.SubscriptionsMapper;
import org.news.web.mapper.UsersMapper;
import org.news.web.service.*;
import org.news.web.utils.UserInfoInterceptorUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/app/news")
@SaIgnore
public class NewsAppController {

    private final INewsService newsService;

    private final NewsMapper newsMapper;

    private final ICreatorsService iCreatorsService;

    private final ICategoriesService iCategoriesService;

    private final ICommentsService iCommentsService;

    private final IHistoryService iHistoryService;

    private final ILikesService iLikesService;

    private final IFavoritesService iFavoritesService;

    private final ISubscriptionsService iSubscriptionsService;

    private final SysOssMapper sysOssMapper;

    private final SubscriptionsMapper subscriptionsMapper;

    private final ICategoriesService categoriesService;

    private final CreatorsMapper creatorsMapper;


    private final UsersMapper usersMapper;

    /**
     * 获取类别的所有新闻信息
     */
    @GetMapping("/listNews/{id}")
    public R<TableDataInfo<NewsVo>> listNews(@PathVariable Integer id,PageQuery pageQuery){
//        获取当前类别下的所有子节点id
        List<Long> ids = categoriesService.getLBListChild(id);
        StringBuilder stringBuilder = new StringBuilder();
        ids.forEach(lid ->{
            stringBuilder.append(lid).append(',');
        });
        System.out.println(id+":child:"+stringBuilder);
        stringBuilder.deleteCharAt(stringBuilder.length()-1);
//        通过当前子节点id查询 所有的新闻
        NewsBo newsBo = new NewsBo();
        newsBo.setCategories(stringBuilder.toString());
        newsBo.setApplyStatus(NewsConstant.FaBu);
        TableDataInfo<NewsVo> newsVoTableDataInfo = newsService.queryPageList(newsBo, pageQuery);
//        返回数据
        return R.ok(newsVoTableDataInfo);
    }

    /**
     * 获取用户关注的新闻列表
     */
    @GetMapping("/AboutListNews/{id}")
    public R<TableDataInfo<NewsVo>> AboutListNews(@PathVariable Integer id,PageQuery pageQuery){
        //获取用户关注的所有作者和栏目信息
        List<SubscriptionsVo> subscriptionsVos = subscriptionsMapper.selectVoList(new LambdaQueryWrapper<Subscriptions>().eq(Subscriptions::getSubscriberId, id));
//        查出 a==b or b ==c
        Set<Long> creators = subscriptionsVos.stream().filter(item -> {
            return item.getStatus() == 2;
        }).map(item -> {
            return item.getTargetCategoryId();
        }).collect(Collectors.toSet());
//
        Set<Long> categories = subscriptionsVos.stream().filter(item -> {
            return item.getStatus() == 1;
        }).map(item -> {
            return item.getTargetCategoryId();
        }).collect(Collectors.toSet());

        Page<NewsVo> result = newsMapper.selectVoPage(pageQuery.build(),new LambdaQueryWrapper<News>()
                .or().eq(News::getAuthorType,NewsConstant.CREATORS_CODE).in(News::getAuthor,creators).or()
            .eq(News::getAuthorType,NewsConstant.LM_CODE).in(News::getAuthor,categories)
        );

        newsService.setNewsImg(result.getRecords());


        return R.ok(TableDataInfo.build(result));
    }

    /**
     * 获取新闻信息
     */
    @GetMapping("/getNews/{id}")
    public R<NewsVo> getNewsById(@PathVariable Integer id){
        NewsVo news = newsService.getNewsById(id);
        return R.ok(news);
    }
    /**
     *  updateNews
     */
    @PostMapping("/updateNews")
    public R<Boolean> createNews(@RequestBody NewsBo bo) throws UnsupportedEncodingException, ClientException {
        return R.ok(newsService.updateByBo(bo));
    }


    /**
     * 获取创作者信息
     */
    @GetMapping("/getCreator/{id}")
    public R<CreatorsVo> getCreator(@PathVariable Integer id){
          CreatorsVo vo = iCreatorsService.getCreatorById(id);
          return R.ok(vo);
    }


    /**
     * 获取栏目信息
     */
    @GetMapping("/getCategorie/{id}")
    public R<CategoriesVo> getCategorie(@PathVariable Integer id){
        CategoriesVo vo = iCategoriesService.getCategorieById(id);
        if(vo.getProfilePicture() == null || vo.getProfilePicture().equals("")){
            vo.setPictureUrl(CategoriesConstant.DFURL());
        }else{
            //       设置ossurl
            SysOss sysOss = sysOssMapper.selectById(vo.getProfilePicture());
            if(sysOss == null || sysOss.getUrl().equals("")){
                vo.setPictureUrl(CategoriesConstant.DFURL());
            }else{
                vo.setPictureUrl(sysOss.getUrl());
            }
        }


        return R.ok(vo);
    }


    /**
     * 获取评论信息
     */
    @GetMapping("/getPL/{id}")
    public TableDataInfo<CommentsVo> getPL(@PathVariable Integer id, PageQuery pageQuery){
        return iCommentsService.getNewsCommentPage(id,pageQuery);
    }


    /**
     * 发送评论信息
     */
    @PostMapping("/sendPL")
    public R<Void> sendPL(@RequestBody CommentsBo bo){
        Boolean aBoolean = iCommentsService.insertByBo(bo);
        if(aBoolean){

            return R.ok("评论成功！");
        }
        return R.fail("评论失败 请重试！");
    }

    /**
     * 删除评论信息
     */
    @GetMapping("/delPL/{id}")
    public R<Void> delPL(@PathVariable Long id){
        Boolean aBoolean = iCommentsService.deleteWithValidByIds(Arrays.asList(id),false);
//        删除评论数量
        if(aBoolean){
            return R.ok("删除成功！");
        }
        return R.fail("删除失败 请重试！");
    }



//    行为模式

    /**
     *   游览行为
     *
     *   收藏行为

     *   关注行为
     *
     *
     */

//    游览

    @GetMapping("/view/{newId}")
    public R<Void> view(HttpServletRequest request,@PathVariable Long newId){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            //给用户id添加游览
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            boolean flag = newsService.addView(userId,newId);

            // 给用户添加历史记录
            HistoryBo historyBo = new HistoryBo();
            historyBo.setNewsId(newId);
            historyBo.setUserId(userId);
            iHistoryService.insertByBo(historyBo);

            return R.ok("用户！");

        }else{
//            单纯添加新闻游览量
            newsMapper.update(new LambdaUpdateWrapper<News>().eq(News::getNewsId, newId).setSql("views = views+1"));
        }
        return R.fail("nouser");
    }

//   喜欢
    @GetMapping("/like/{newId}")
    public R<Void> like(HttpServletRequest request,@PathVariable Long newId){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            //给用户添加喜欢
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            LikesBo likesBo = new LikesBo();
            likesBo.setNewsId(newId);
            likesBo.setUserId(userId);
            iLikesService.insertByBo(likesBo);
        }else {
            return R.fail("nouser");
        }
        return R.ok("点赞成功");
    }

    //不喜欢
    @GetMapping("/nolike/{newId}")
    public R<Void> nolike(HttpServletRequest request,@PathVariable Long newId){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            //给用户取消喜欢
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            iLikesService.nolike(userId,newId);
        }else {
            return R.fail("nouser");
        }
        return R.ok("取消点赞");
    }

//    是否喜欢
    @GetMapping("/islike/{newId}")
    public R<Boolean> islike(HttpServletRequest request,@PathVariable Long newId){
        boolean isLike = true;
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            //给用户id添加游览
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            isLike = iLikesService.isLike(userId,newId);
        }else {
            return R.fail("nouser");
        }
        return R.ok(isLike);
    }



    @GetMapping("/isfavo/{newId}")
    public R<Boolean> isfavo(HttpServletRequest request,@PathVariable Long newId){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        boolean flag = true;
        if(aBoolean){
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            flag = iFavoritesService.isFavo(userId,newId);
        }else {
            return R.fail("nouser");
        }
        return R.ok(flag);
    }

    @GetMapping("/favo/{newId}")
    public R<Void> favo(HttpServletRequest request,@PathVariable Long newId){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            //给用户id添加游览
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            int flag = iFavoritesService.favo(userId,newId);
        }else {
            return R.fail("nouser");
        }
        return R.ok("收藏成功");
    }


    @GetMapping("/nofavo/{newId}")
    public R<Void> nofavo(HttpServletRequest request,@PathVariable Long newId){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            //给用户id添加游览
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            int flag = iFavoritesService.nofavo(userId,newId);
        }else {
            return R.fail("nouser");
        }
        return R.ok("取消收藏！");
    }


//    订阅
//    是否订阅
    @GetMapping("/isSub/{type}/{id}")
    public R<Boolean> isSub(HttpServletRequest request,@PathVariable Long type,@PathVariable Long id){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        boolean flag = true;
        if(aBoolean){
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            SubscriptionsBo subscriptionsBo = new SubscriptionsBo();
//            添加用户
            subscriptionsBo.setSubscriberId(userId);
//            添加状态
            subscriptionsBo.setStatus(type);
//            添加栏目或作者
            subscriptionsBo.setTargetCategoryId(id);
            flag = iSubscriptionsService.isSub(subscriptionsBo);
        }else {
            return R.fail("nouser");
        }
        return R.ok(flag);
    }
//    添加订阅
    @GetMapping("/sub/{type}/{id}")
    public R<Void> Sub(HttpServletRequest request,@PathVariable Long type,@PathVariable Long id){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            SubscriptionsBo subscriptionsBo = new SubscriptionsBo();
//            添加用户
            subscriptionsBo.setSubscriberId(userId);
//            添加状态
            subscriptionsBo.setStatus(type);
//            添加栏目或作者
            subscriptionsBo.setTargetCategoryId(id);

            iSubscriptionsService.insertByBo(subscriptionsBo);
        }else {
            return R.fail("nouser");
        }
        return R.ok();
    }

//    删除订阅
    @GetMapping("/noSub/{type}/{id}")
    public R<Void> noSub(HttpServletRequest request,@PathVariable Long type,@PathVariable Long id){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean){
            Long userId = UserInfoInterceptorUtils.getUserId(request);
//            查询订阅是否存在
            SubscriptionsBo subscriptionsBo = new SubscriptionsBo();
//            添加用户
            subscriptionsBo.setSubscriberId(userId);
//            添加状态
            subscriptionsBo.setStatus(type);
//            添加栏目或作者
            subscriptionsBo.setTargetCategoryId(id);
            if (!iSubscriptionsService.isSub(subscriptionsBo)) {
                throw new ServiceException("作者或栏目不存在 删除失败");
            }
            Subscriptions subscriptions = subscriptionsMapper.selectOne(new LambdaQueryWrapper<Subscriptions>()
                .eq(Subscriptions::getStatus, subscriptionsBo.getStatus())
                .eq(Subscriptions::getTargetCategoryId, subscriptionsBo.getTargetCategoryId())
                .eq(Subscriptions::getSubscriberId, subscriptionsBo.getSubscriberId())
            );
            iSubscriptionsService.deleteWithValidByIds(Arrays.asList(subscriptions.getSubscriptionId()),false);
        }else {
            return R.fail("nouser");
        }
        return R.ok();
    }


    @GetMapping("/getLikeCount/{id}")
    public R<Long> getLikeCount(@PathVariable Long id){
        return R.ok(newsService.getLikeCount(id));
    }


    @GetMapping("/getFavoCount/{id}")
    public R<Long> getFavoCount(@PathVariable Long id){
        return R.ok(newsService.getFavoCount(id));
    }

    @GetMapping("/getAuthorAllViewCount/{id}")
    public R<Long> getAuthorAllLikeCount(@PathVariable Long id){
        return R.ok(newsService.AuthorAllViewCount(id));
    }

    @GetMapping("/getAuthorAllCommCount/{id}")
    public R<Long> getAuthorAllCommCount(@PathVariable Long id){
        return R.ok(newsService.AuthorAllCommCount(id));
    }

//    获取顶级栏目信息
    @GetMapping("/listCategories")
    public R<List<CategoriesVo>> list(CategoriesBo bo){
        List<CategoriesVo> list = categoriesService.queryList(bo);
        return R.ok(list);
    }


//    获取新闻的list
    @GetMapping("/news/list")
    public TableDataInfo<NewsVo> list(HttpServletRequest request,NewsBo bo, PageQuery pageQuery) {
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean) {
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            Creators creators = creatorsMapper.selectOne(new LambdaQueryWrapper<Creators>().eq(Creators::getUserId, userId));
            if(creators != null){
                bo.setAuthor(String.valueOf(creators.getCreatorId()));
            }else{
                return null;
            }
            return newsService.queryPageList(bo, pageQuery);
        }else{
            return null;
        }
    }

//     delnews
    @GetMapping("/delete/{id}")
    public R<Void> delNews(HttpServletRequest request,@PathVariable Long id){
        Boolean aBoolean = UserInfoInterceptorUtils.CheckUserInfoKey(request);
        if(aBoolean) {
            //判断该文章是不是属于自己
            Long userId = UserInfoInterceptorUtils.getUserId(request);
            Creators creators = creatorsMapper.selectOne(new LambdaQueryWrapper<Creators>().eq(Creators::getUserId, userId));
            if (creators == null){
                return R.fail("不能删除别人文章！！！");
            }
            Long count = newsMapper.selectCount(new LambdaQueryWrapper<News>().eq(News::getNewsId, id).eq(News::getAuthorType, NewsConstant.CREATORS_CODE).eq(News::getAuthor, creators.getCreatorId()));
            if(count <= 0){
                return R.fail("该文章不存在！！！");
            }
            newsMapper.delete(new LambdaQueryWrapper<News>().eq(News::getNewsId, id).eq(News::getAuthorType, NewsConstant.CREATORS_CODE).eq(News::getAuthor, creators.getCreatorId()));
            return R.ok();
        }else{
            return R.fail("nouser");
        }
    }
}
